package com.rivues.module.platform.web.interceptor;

import java.util.Date;
import java.util.Enumeration;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.shiro.SecurityUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.ModelAndView;

import com.rivues.core.RivuDataContext;
import com.rivues.module.platform.web.handler.Handler;
import com.rivues.module.platform.web.model.QueryLog;
import com.rivues.module.platform.web.model.RequestLog;
import com.rivues.module.platform.web.model.User;
import com.rivues.module.report.web.handler.ReportHandler;
import com.rivues.util.RivuTools;
import com.rivues.util.log.Logger;
import com.rivues.util.log.LoggerFactory;
import com.rivues.util.service.cache.CacheHelper;
import com.rivues.util.service.system.DataPersistenceService;

/**
 * 系统访问记录
 * @author admin
 *
 */
public class LogIntercreptorHandler implements org.springframework.web.servlet.HandlerInterceptor{
	private final Logger log = LoggerFactory.getLogger(LogIntercreptorHandler.class);   
	@Override
	public void afterCompletion(HttpServletRequest request,
			HttpServletResponse arg1, Object arg2, Exception arg3)
			throws Exception {
		HandlerMethod  handlerMethod = (HandlerMethod ) arg2 ;
	    Handler hander = (Handler)handlerMethod.getBean() ;
	    RequestMapping obj = handlerMethod.getMethod().getAnnotation(RequestMapping.class) ;
	    Object conf = CacheHelper.getDistributedDictionaryCacheBean().getCacheObject("system.config.log.insert.model", hander.getOrgi()) ;
	    if(conf!=null&&conf.toString().indexOf(obj.type())>=0){
	    	RequestLog log = new RequestLog();
		    log.setStarttime(hander.getIntime()) ;
		    
			log.setClassname(hander.getClass().toString()) ;
			log.setName(obj.name());
			log.setFuntype(obj.type());
			log.setMethodname(handlerMethod.toString()) ;
			log.setIp(request.getRemoteAddr()) ;
			log.setHostname(request.getRemoteHost()) ;
			log.setEndtime(new Date());
			log.setType(RivuDataContext.LogTypeEnum.REQUEST.toString()) ;
			log.setOrgi(hander.getOrgi());
			log.setQuerytime(log.getEndtime().getTime()-log.getStarttime().getTime()) ;
			log.setUrl(request.getRequestURI()) ;
			log.setFlowid(hander.getFlowid()) ;
			log.setError(String.valueOf(hander.isError())) ;
			User user = (User) SecurityUtils.getSubject().getSession().getAttribute(RivuDataContext.USER_SESSION_NAME) ;
			if(user!=null){
				log.setUserid(user.getId()) ;
				log.setUsername(user.getUsername()) ;
				log.setUsermail(user.getEmail()) ;
			}else if("passwordupdatedo".equals(obj.type())){
				log.setUsername(request.getParameter("username")) ;
			}else{
				log.setUserid(RivuTools.md5(request.getSession(true).getId())) ;
				log.setUsername(RivuDataContext.GUEST_USER) ;
			}
			log.setStatues(hander.isError()?"0":"1") ;			//执行成功还是失败
			StringBuffer str = new StringBuffer();
			Enumeration<String> names = request.getParameterNames();
			while(names.hasMoreElements()){
				String paraName=(String)names.nextElement();
				str.append(paraName).append("=").append(request.getParameter(paraName)).append(",");
			}
			log.setParameters(str.toString());

			DataPersistenceService.persistence(log) ;
	    }
	    
	}

	@Override
	public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1,
			Object arg2, ModelAndView arg3) throws Exception {
		
	}

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
			Object arg2) throws Exception {
		User user = (User)(SecurityUtils.getSubject().getSession().getAttribute(RivuDataContext.USER_SESSION_NAME)) ;
		HandlerMethod  handlerMethod = (HandlerMethod ) arg2 ;
	    Handler hander = (Handler)handlerMethod.getBean() ;
		if(user!=null){
			String orgi = user.getOrgi() ;
			hander.setOrgi(orgi) ;
		}else{
			String uri = request.getRequestURI() ;
			if(uri.startsWith("/")){
				uri = uri.substring(1) ;
				if(uri.indexOf("/")>0){
					uri = uri.substring(0 , uri.indexOf("/")) ;
				}
			}else{
				uri = "LOGIN" ;
			}
			hander.setOrgi(uri) ;
		}
		hander.setFlowid(String.valueOf(System.nanoTime())) ;
		if(hander.getLog()==null){
			hander.setLog(com.rivues.util.log.LoggerFactory.getLogger(hander.getClass())) ;
		}
		/**
		 * 以下代码收集 报表运行信息日志
		 */
		RequestMapping requestMapping = handlerMethod.getMethod().getAnnotation(RequestMapping.class) ;
		if(requestMapping.subtype()!=null && (requestMapping.subtype().equals("report")||requestMapping.subtype().equals("custom")||requestMapping.subtype().equals("query"))){
			QueryLog reportQueryLog = new QueryLog();
			((ReportHandler)hander).setQueryLog(reportQueryLog) ;
			reportQueryLog.setName(requestMapping.name());
			reportQueryLog.setClassname(hander.getClass().toString()) ;
			reportQueryLog.setMethodname(handlerMethod.toString()) ;
			if(user!=null){
				reportQueryLog.setUsername(user.getUsername());
				reportQueryLog.setUserid(user.getId());
				reportQueryLog.setUsermail(user.getEmail());
			}
			reportQueryLog.setIp(request.getRemoteAddr()) ;
			reportQueryLog.setHostname(request.getRemoteHost()) ;
			reportQueryLog.setEndtime(new Date());
			reportQueryLog.setType(RivuDataContext.LogTypeEnum.REQUEST.toString()) ;
			reportQueryLog.setOrgi(hander.getOrgi());
			reportQueryLog.setUrl(request.getRequestURI()) ;
			reportQueryLog.setFlowid(hander.getFlowid()) ;
			reportQueryLog.setError(String.valueOf(hander.isError())) ;
			if(user!=null){
				reportQueryLog.setUserid(user.getId()) ;
				reportQueryLog.setUsername(user.getUsername()) ;
				reportQueryLog.setUsermail(user.getEmail()) ;
			}
			reportQueryLog.setStatues(hander.isError()?"0":"1") ;			//执行成功还是失败
			StringBuffer str = new StringBuffer();
			Enumeration<String> names = request.getParameterNames();
			while(names.hasMoreElements()){
				String paraName=(String)names.nextElement();
				str.append(paraName).append("=").append(request.getParameter(paraName)).append(",");
			}
			reportQueryLog.setParameters(str.toString());
		}
		//结束
		hander.setIntime(new Date()) ;
		hander.setError(false) ;
		return true;
	}
}
